package zcj.stu;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

@Slf4j
public class C24 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
        RequestMappingHandlerAdapter handlerAdapter=new RequestMappingHandlerAdapter();
        handlerAdapter.setApplicationContext(context);
        handlerAdapter.afterPropertiesSet();
        log.info("开始...");
        showHandlerAdapter(handlerAdapter);
        log.info("模拟用Controller foo方法");
        Method getDataBinderFactory = handlerAdapter.getClass().getDeclaredMethod("getDataBinderFactory", HandlerMethod.class);
        getDataBinderFactory.setAccessible(true);
        getDataBinderFactory.invoke(handlerAdapter,new HandlerMethod(new WebConfig.Controller1(), WebConfig.Controller1.class.getMethod("foo")));
        showHandlerAdapter(handlerAdapter);

        showHandlerAdapter(handlerAdapter);

    }
    public static void showHandlerAdapter(RequestMappingHandlerAdapter handlerAdapter) throws NoSuchFieldException, IllegalAccessException {
        Field  initBinderCache = handlerAdapter.getClass().getDeclaredField("initBinderCache");
        initBinderCache.setAccessible(true);
        Map<Class<?>, Set<Method>> initBinderMap =(Map<Class<?>, Set<Method>>) initBinderCache.get(handlerAdapter);
        initBinderMap.forEach((k,v)->{
            System.out.print(k.getSimpleName()+" ");
            v.forEach((method -> {
                System.out.print(method.getName()+"");
            }));
            System.out.println();
        });
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        Field  initBinderAdviceCache = handlerAdapter.getClass().getDeclaredField("initBinderAdviceCache");
        initBinderAdviceCache.setAccessible(true);
        java.util.Map<org.springframework.web.method.ControllerAdviceBean,java.util.Set<java.lang.reflect.Method>> initBinderAdviceMap =(java.util.Map<org.springframework.web.method.ControllerAdviceBean,java.util.Set<java.lang.reflect.Method>>) initBinderAdviceCache.get(handlerAdapter);
        initBinderAdviceMap.forEach((k,v)->{
            System.out.print(k.getClass().getSimpleName()+" ");
            v.stream().forEach((method -> {
                System.out.print( method.getName()+" ");
            }));
            System.out.println();
        });
    }
}
